package study.itwill.team5.member;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import study.itwill.common.DBHandler;
import study.itwill.common.DateTime;

/**
 * 회원로그 - 추가, 삭제, 조회, 리스트(검색포함) 기능을 가진 클래스
 */
public class Log {
	
	// Logger 클래스의 인스턴스를 받아온다.
	static Logger logger = Logger.getLogger(Log.class);
		
	private static final String TABLE = "member_log";
	
	// 데이터베이스 제어 객체에 대한 참조
	DBHandler db = null;
	
	/** 현재시간 데이터 저장을 위한 SQL구문 작성 */
	String datetime = DateTime.getInstance().getNowDateTimeString();
	
	public Log() {
		// DB객체에 대한 참조 연결
		db = DBHandler.getInstance();
	}
	
	
	/**
	 * 로그 추가
	 * @param	member_seq	- 회원의 일련번호
	 * @param	page		- 로그 페이지주소
	 * @param	user_ip		- 접속 아이피
	 * @param	user_device	- 접속기기정보
	 * @return	int  		- 추가된 로그의 일련번호
	 */
	public int addLog(int member_seq, String page, String user_ip,
			String user_device) {
		//-----------------------------------------
		// 메서드 시작
		//-----------------------------------------
		logger.debug("=============== method start >> addLog");
		logger.debug("[PARAMS] member_seq=" + member_seq);
		logger.debug("[PARAMS] page=" + page);
		logger.debug("[PARAMS] user_ip=" + user_ip);
		logger.debug("[PARAMS] user_device=" + user_device);
		
		int seq = -1;
		
		// SQL 인젝션 방어
		page = page.replace("'", "\'");
		user_ip = user_ip.replace("'", "\'");
		user_device = user_device.replace("'", "\'");
		
		// 트랜젝션에 대한 판단이 잘 서지 않는다면, 무조건 하면 된다.
		db.beginTrans();
		
		// INSERT 처리를 위한 구현
		String sql = "INSERT INTO member_log("
	            + "member_seq, page, user_ip, user_device, reg_date"
	            + ") VALUES (%d, '%s', '%s', '%s', '%s');";
		
		boolean result = db.execSql(sql, member_seq, page, user_ip, user_device, datetime);
		
		//-----------------------------------------
		// 결과처리
		//-----------------------------------------
		if(result) {
			db.commit();
			seq = db.getMax(TABLE, "seq", null);
			logger.debug("처리결과 >> " + seq + "번 로그 추가 성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 로그 추가 실패");
		}
		
		logger.debug("=============== method end >> addLog");
		
		
		return seq;
	}
	
	/**
	 * 로그삭제
	 * @param	seq		- 로그일련번호
	 * @return	true	- 로그삭제 성공 / false - 로그삭제 실패
	 */
	public boolean deleteLog(int seq) {
		logger.debug("=============== method start >> deleteLog");
		logger.debug("[PARAMS] seq=" + seq);
		
		boolean result = false;
		
		db.beginTrans();
		
		String sql = "DELETE FROM member_log WHERE seq = %d;";
		result = db.execSql(sql, seq);
		
		if(result) {
			db.commit();
			logger.debug("처리결과 >> " + seq + "번 로그 삭제 성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 로그 삭제 실패 ");
		}
		
		logger.debug("=============== method end >> deleteLog");
		
		return result;
	}
	
	/**
	 * 로그정보 조회
	 * @param	seq		- 로그일련번호
	 * @return	LogItem - 로그 한개의 정보를 객체로 리턴 
	 */
	public LogItem viewLog(int seq) {
		logger.debug("=============== method start >> viewLog");
		logger.debug("[PARAMS] seq=" + seq);
		
		LogItem item = null;
		
		// 데이터 조회
		String sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
				+ "FROM member_log, member "
				+ "WHERE member_log.member_seq = member.seq and member_log.seq = %d;";
		
		ResultSet rs = db.getResult(sql, seq);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				rs.next();
				
				// 1) ResultSet의 모든 데이터를 변수로 추출
				int log_seq = rs.getInt(1);
				int member_seq = rs.getInt(2);
				String user_name = rs.getString(3);
				String page = rs.getString(4);
				String user_ip = rs.getString(5);
				String user_device = rs.getString(6);
				String reg_date = rs.getString(7);
				
				// 2) 추출된 값을 객체로 구성
				item = new LogItem(log_seq, member_seq, user_name, page, user_ip, user_device, reg_date);
				
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 3) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(item == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공");
			logger.debug(item.toString());
		}
				
		logger.debug("=============== method end >> viewLog");
		
		return item;
	}
	
	/**
	 * 로그 정보 리스트조회
	 * @param	choice : 검색조건 (0:로그전체, 1:이메일, 2:페이지, 3:아이피, 4:디바이스)
	 * @param	search : 검색값
	 * @return	ArrayList<LogItem> - 로그정보를 객체배열 형태로 리턴 
	 */
	public ArrayList<LogItem> listLog(int choice, String search) {
		logger.debug("=============== method start >> listLog");
		logger.debug("[PARAMS] choice=" + choice);
		logger.debug("[PARAMS] search=" + search);
		
		ArrayList<LogItem> list = null;
		
		String sql = null;
		
		/*
		 *  로그 검색을 위한 파라미터 정의
		 *  0, null : 로그 전체리스트 검색
		 *  		(전체리스트 검색은 오버로딩 정의로 숫자값 하나만을 파라미터로 받을수 있다)
		 *  1, "이메일 검색"
		 *  2, "페이지 검색"
		 *  3, "아이피 검색"
		 *  4, "디바이스 검색"
		 */
		switch(choice) {
		case 0:
			sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
					+ "FROM member_log, member "
					+ "WHERE member_log.member_seq = member.seq;";
			break;
			
		case 1:
			sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
					+ "FROM member_log, member "
					+ "WHERE member_log.member_seq = member.seq and member.email like '%%" + search + "%%';";
			break;
		
		case 2:
			sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
					+ "FROM member_log, member "
					+ "WHERE member_log.member_seq = member.seq and page like '%%" + search + "%%';";
			break;
			
		case 3:
			sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
					+ "FROM member_log, member "
					+ "WHERE member_log.member_seq = member.seq and user_ip like '%%" + search + "%%';";
			break;
			
		case 4:
			sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
					+ "FROM member_log, member "
					+ "WHERE member_log.member_seq = member.seq and user_device like '%%" + search + "%%';";
			break;
			
		default:
			System.out.println("검색조건 선택이 올바르지 않습니다.");
			sql = "SELECT member_log.seq, member_log.member_seq, member.user_name, page, user_ip, user_device, member_log.reg_date "
					+ "FROM member_log, member "
					+ "WHERE member.seq=-1;";
			break;
		}
			
		
		ResultSet rs = db.getResult(sql);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<LogItem>();
				
				while(rs.next()) {
					
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int seq = rs.getInt(1);
					int member_seq = rs.getInt(2);
					String user_name = rs.getString(3);
					String page = rs.getString(4);
					String user_ip = rs.getString(5);
					String user_device = rs.getString(6);
					String reg_date = rs.getString(7);
					
					// 2) 추출된 값을 객체로 구성
					LogItem item = new LogItem(seq, member_seq, user_name, page, user_ip, user_device, reg_date);
					
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(list == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공 >> " + list.size() + "건 조회됨");
		}
		
		logger.debug("=============== method end >> listLog");
		
		return list;
	}
	
	/**
	 * 로그 정보 전체리스트 검색을 위한 오버로딩 정의
	 * @param choice					- 0으로 파라미터를 받을시 전체리스트 조회
	 * @return ArrayList<LogItem>		- 0과 null을 오버로딩된 메서드로 반환
	 */
	public ArrayList<LogItem> listLog(int choice) {
		return listLog(choice, null);
	}
}
